#!/usr/bin/env python
#-*- coding: utf-8 -*-
import gtk
import gnome.ui
import gnomevfs
import gobject
import os

class IconFactory(object):
	thumbFactory = gnome.ui.ThumbnailFactory(gnome.ui.THUMBNAIL_SIZE_LARGE)
	iconTheme = gtk.icon_theme_get_default()
	
	def __init__(self):
		self.thumbFactory.__gobject_init__()
		
	def iconNameForURI(self, uri, mime = None):
		if not mime:
			mime = gnomevfs.get_mime_type(uri)
		iconName = gnome.ui.icon_lookup(self.iconTheme, self.thumbFactory, uri, mime, 0)[0]
		return iconName
	
	def getThumbnailForURI(self, uri, iconSize, mime = None, shouldThumbnail = False): 
		pixName = self.thumbFactory.lookup(uri, 0)
		if pixName and os.path.isfile(pixName):
			return gtk.gdk.pixbuf_new_from_file_at_size(pixName, iconSize, iconSize)
		if not shouldThumbnail:
			return None
		if not mime:
			mime = gnomevfs.get_mime_type(uri)
		if not self.thumbFactory.can_thumbnail(uri ,mime, 0):
			return None
		if self.thumbFactory.has_valid_failed_thumbnail(uri, 0):
			return None
		pix = self.thumbFactory.generate_thumbnail(uri, mime)
		if pix:
			self.thumbFactory.save_thumbnail(pix, uri, 0)
			return pix.scale_simple(iconSize, iconSize, gtk.gdk.INTERP_HYPER)
		return None
					
	def iconForURI(self, uri, iconSize, getThumbnails = True, shouldThumbnail = False):
		mime = gnomevfs.get_mime_type(uri)
		if getThumbnails:
			pix = self.getThumbnailForURI(uri, iconSize, mime, shouldThumbnail)
			if pix:
				return pix
		iconName = self.iconNameForURI(uri, mime)
		return self.iconForIconName(iconName, iconSize)
		
	def iconForIconName(self, iconName, iconSize):
		if iconName == '':
			return None
		if isinstance(iconSize, gtk.IconSize):
			iconSize = gtk.icon_size_lookup(iconSize)[0]
		try:
			iconNameModified = os.path.basename(iconName).rsplit('.',1)[0] # only base filename without extension
			info = self.iconTheme.lookup_icon(iconNameModified, iconSize, gtk.ICON_LOOKUP_FORCE_SVG | gtk.ICON_LOOKUP_USE_BUILTIN)
			if info:
				icon = self.iconTheme.load_icon(iconNameModified, iconSize, gtk.ICON_LOOKUP_FORCE_SVG | gtk.ICON_LOOKUP_USE_BUILTIN)
			elif os.path.isfile(iconName):
				icon = self.iconFromFileName(iconName, iconSize)
			else: 
				icon = self.iconSearchInDataPath(iconName, iconSize)
			if icon and (icon.get_width() != iconSize or icon.get_height() != iconSize):
				icon = icon.scale_simple(iconSize, iconSize, gtk.gdk.INTERP_NEAREST)
			return icon
		except gobject.GError, message:
			print "Can't load icon:", message, iconName 
			
	def iconFromFileName(self, iconName, iconSize = -1):
		if os.path.isfile(iconName):
			try:
				return gtk.gdk.pixbuf_new_from_file_at_size(iconName, -1, iconSize)
			except:
				pass
		return None
		
	def iconSearchInDataPath(self, iconName, iconSize):
		dataFolders = None
		
		if os.environ.has_key("XDG_DATA_DIRS"):
			dataFolders = os.environ["XDG_DATA_DIRS"]
			
		if not dataFolders:
			dataFolders = "/usr/local/share/:/usr/share/"
			
		for dataFolder in dataFolders.split(':'):
			paths = (os.path.join(dataFolders, "pixmaps", iconName), os.path.join(dataFolders, "icons", iconName))
			for path in paths:
				if os.path.isfile(path):
					icon = self.iconFromFileName(path, iconSize)
					if icon:
						return icon
		return None
		
	def greyscaleIcon(self, iconAsPixBuf):
		pixBuf = iconAsPixBuf.copy()
		for row in pixBuf.get_pixels_array():
			for pix in row:
				pix[0] = pix[1] = pix[2] = (int(pix[0]) + int(pix[1]) + int(pix[2])) / 3
		return pixBuf
	
	def colorshift(self, iconAsPixBuf, shift):
		pixBuf = iconAsPixBuf.copy()
		for row in pixBuf.get_pixels_array():
			for pix in row:
				pix[0] = min(255, int(pix[0]) + shift)
				pix[1] = min(255, int(pix[1]) + shift)
				pix[2] = min(255, int(pix[2]) + shift)
		return pixBuf
		
